package com.ruoyi.quartz.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.quartz.domain.StockBasic;
import com.ruoyi.quartz.domain.StockBear;
import com.ruoyi.quartz.domain.StockDaily;
import com.ruoyi.quartz.domain.StockTransactionDaily;
import com.ruoyi.quartz.service.IStockBasicService;
import com.ruoyi.quartz.service.IStockBearService;
import com.ruoyi.quartz.service.IStockDailyService;
import com.ruoyi.quartz.service.IStockTransactionDailyService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author :chenzengzhi
 * @date :2023/11/22 14:51
 * @logo :#^_^#
 */
@Component("stockBasicTask")
public class StockBasicTask {

    public static final String stockJson = "{\"api_name\":\"stock_company\",\"token\":\"fab9535839c57860d2525efff8785ec3942ea386d0d304d7fd762d1b\",\"params\":{\"exchange\":\"SZSE\"},\"fields\":\"ts_code,exchange,setup_date\"}";

    public static final String stockUrl = "http://api.tushare.pro";

    public static final String dailyUrl = "https://50.push2.eastmoney.com/api/qt/stock/details/sse?fields1=f1,f2,f3,f4&fields2=f51,f52,f53,f54,f55&mpi=2000&fltt=2&pos=-0&secid=tsCode&wbp2u=|0|0|0|web";

    public static final String updateUrl = "https://push2his.eastmoney.com/api/qt/stock/kline/get?secid=tsCode&fields1=f1%2Cf2%2Cf3%2Cf4%2Cf5%2Cf6&fields2=f51%2Cf52%2Cf53%2Cf54%2Cf55%2Cf56%2Cf57%2Cf58%2Cf59%2Cf60%2Cf61&klt=101&fqt=1&beg=0&end=20500101&smplmt=460&lmt=1000000&_=1701049917104";

    @Resource
    private IStockBasicService stockBasicService;

    @Resource
    private IStockTransactionDailyService stockTransactionDailyService;

    @Resource
    private IStockDailyService stockDailyService;

    @Resource
    private IStockBearService stockBearService;

    public void stockNoParams() {

        String response = HttpUtils.sendPost(stockUrl, stockJson);
        JSONObject jsonObject = JSON.parseObject(response);
        JSONObject data = jsonObject.getJSONObject("data");
        JSONArray items = data.getJSONArray("items");
        StockBasic stockBasic = null;
        for (int i=0;i<items.size();i++){
            JSONArray item = items.getJSONArray(i);
            stockBasic = new StockBasic();
            stockBasic.setTsCode(item.getString(0));
            stockBasic.setExchange(item.getString(1));
            stockBasic.setListDate(item.getString(2));
            stockBasicService.insertStockBasic(stockBasic);

        }

    }

    public void stockFile() throws IOException {

        StringBuilder result = new StringBuilder();

        InputStream io = new FileInputStream("D:\\1111.txt");

        BufferedReader br = new BufferedReader(new InputStreamReader(io));

        String ret = "";
        while ((ret = br.readLine()) != null)
        {
            if (ret != null && !ret.trim().equals(""))
            {
                result.append(new String(ret.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));
            }
        }

        JSONObject jsonObject = JSON.parseObject(result.toString());
        JSONObject data = jsonObject.getJSONObject("data");
        JSONArray items = data.getJSONArray("items");
        StockBasic stockBasic = null;
        for (int i=0;i<items.size();i++){
            JSONArray item = items.getJSONArray(i);
            stockBasic = new StockBasic();
            stockBasic.setTsCode(item.getString(0));
            stockBasic.setSymbol(item.getString(1));
            stockBasic.setName(item.getString(2));
            stockBasic.setIndustry(item.getString(3));
            stockBasic.setExchange(item.getString(4));
            stockBasic.setListDate(item.getString(5));
            stockBasicService.insertStockBasic(stockBasic);

        }
    }

    public void transactionDaily() throws InterruptedException {
        List<StockBasic> list  = stockBasicService.selectStockBasicList(null);
        StockTransactionDaily std = null;
        StringBuilder code = new StringBuilder();
        JSONObject data = null;
        JSONObject tmp = null;
        JSONArray jsonArray = null;
        String result = "";
        String url = "";
        for (StockBasic sb :list){

            if ("SSE".equals(sb.getExchange())){
                code.append("1.").append(sb.getSymbol());
            }else {
                code.append("0.").append(sb.getSymbol());
            }
            url = dailyUrl.replaceAll("tsCode",code.toString());
            code.delete(0,code.length());
            System.out.println(url);
            result = HttpUtils.sendGet(url,0);

            tmp = JSON.parseObject(result.substring(result.indexOf('{')));

            data = tmp.getJSONObject("data");

            jsonArray = data.getJSONArray("details");

            std = new StockTransactionDaily();

            std.setTsCode(sb.getTsCode());
            std.setCode(data.getString("code"));
            std.setMarket(data.getInteger("market"));
            std.setPrePrice(data.getBigDecimal("prePrice"));
            std.setDetails(jsonArray.toJSONString());
            std.setTransactionDate(DateUtils.dateTime());
            std.setName(sb.getName());
            stockTransactionDailyService.insertStockTransactionDaily(std);
            Thread.sleep(500);


        }


    }

    public void transactionUpdate() throws InterruptedException {
        List<StockBasic> list  = stockBasicService.selectStockBasicList(null);
        StringBuilder code = new StringBuilder();
        String url = "";
        JSONObject jsonObject = null;
        JSONObject data = null;
        String result ="";
        JSONArray klines = null;
        String tmp = "";
        String tmps[] = null;
        BigDecimal floatShare = null;
        DecimalFormat df = new DecimalFormat("#.000");


        for (StockBasic sb:list){
            if (sb.getFloatShare()!=null){
                continue;
            }
            if ("SSE".equals(sb.getExchange())){
                code.append("1.").append(sb.getSymbol());
            }else {
                code.append("0.").append(sb.getSymbol());
            }



            url = updateUrl.replaceAll("tsCode",code.toString());
            code.delete(0,code.length());
            System.out.println(url);
            result = HttpUtils.sendGet(url);
            jsonObject = JSON.parseObject(result);
            data = jsonObject.getJSONObject("data");
            klines = data.getJSONArray("klines");

            tmp = klines.getString(klines.size()-1);

            tmps = tmp.split(",");

            double f = Double.parseDouble(tmps[5]);
            double fc = Double.parseDouble(tmps[10]);
            double cc = f/fc;
            floatShare = new BigDecimal(cc);

            System.out.println(floatShare.setScale(3,BigDecimal.ROUND_HALF_UP));
            sb.setFloatShare(floatShare.setScale(3,BigDecimal.ROUND_HALF_UP));

            stockBasicService.updateStockBasic(sb);
            Thread.sleep(100);

        }

    }


    public void daily(String date){

        JSONObject request = new JSONObject();
        request.put("api_name","daily");
        request.put("token","fab9535839c57860d2525efff8785ec3942ea386d0d304d7fd762d1b");
        Map<String,Object> params = new HashMap<>();
        //params.put("trade_date",DateUtils.dateTime());
        params.put("trade_date",date);
        request.put("params",params);
        request.put("fields","ts_code,trade_date,open,high,low,close,pre_close,change,pct_chg,vol,amount");

        String response = HttpUtils.sendPost(stockUrl,request.toJSONString());
        JSONObject jsonObject = JSON.parseObject(response);
        JSONObject data = jsonObject.getJSONObject("data");
        JSONArray items = data.getJSONArray("items");

        StockDaily stockDaily = null;
        StockBear stockBear = null;
        JSONArray item = null;
        BigDecimal bd = null;
        int flag = 0;

        List<StockBasic> list  = stockBasicService.selectStockBasicList(null);
        for (int i=0;i<items.size();i++){
            item = items.getJSONArray(i);
            stockDaily = new StockDaily();
            stockBear = new StockBear();
            stockDaily.setTsCode(item.getString(0));
            stockDaily.setTradeDate(item.getString(1));
            stockDaily.setOpened(item.getBigDecimal(2));
            stockDaily.setHigh(item.getBigDecimal(3));
            stockDaily.setLow(item.getBigDecimal(4));
            stockDaily.setClosed(item.getBigDecimal(5));
            stockDaily.setPreClosed(item.getBigDecimal(6));
            stockDaily.setChanged(item.getBigDecimal(7));
            stockDaily.setPctChg(item.getBigDecimal(8));
            stockDaily.setVol(item.getBigDecimal(9));
            stockDaily.setAmount(item.getBigDecimal(10));

            stockBear.setTsCode(item.getString(0));
            stockBear.setClosedPrices(item.getBigDecimal(5).toString());
            flag = item.getBigDecimal(7).compareTo(BigDecimal.ZERO);
            if (flag==0){
                stockBear.setClosedFlags("0");
            }else if (flag == -1){
                stockBear.setClosedFlags("1");
            }else {
                stockBear.setClosedFlags("2");
            }
            for (StockBasic sb :list){
                if (sb.getTsCode().equals(stockDaily.getTsCode())){

                    bd = stockDaily.getVol().divide(sb.getFloatShare(),2,BigDecimal.ROUND_HALF_UP);
                    stockDaily.setTurnoverRate(bd);
                    stockBear.setTurnoverRates(bd.toString());
                    stockBear.setName(sb.getName());
                    break;
                }
            }

            stockDailyService.insertStockDaily(stockDaily);
            stockBearService.insertStockBear(stockBear);
        }
    }

    public void bear(String date){

        JSONObject request = new JSONObject();
        request.put("api_name","daily");
        request.put("token","fab9535839c57860d2525efff8785ec3942ea386d0d304d7fd762d1b");
        Map<String,Object> params = new HashMap<>();
        params.put("trade_date",date);
        request.put("params",params);
        request.put("fields","ts_code,trade_date,open,high,low,close,pre_close,change,pct_chg,vol,amount");

        String response = HttpUtils.sendPost(stockUrl,request.toJSONString());
        JSONObject jsonObject = JSON.parseObject(response);
        JSONObject data = jsonObject.getJSONObject("data");
        JSONArray items = data.getJSONArray("items");

        StockDaily stockDaily = null;
        StockBear stockBear = null;
        JSONArray item = null;
        BigDecimal bd = null;
        int flag = 0;
        List<StockBear> bears = stockBearService.selectStockBearList(null);
        List<StockBasic> list  = stockBasicService.selectStockBasicList(null);
        for (int i=0;i<items.size();i++){
            item = items.getJSONArray(i);
            stockDaily = new StockDaily();

            stockDaily.setTsCode(item.getString(0));
            stockDaily.setTradeDate(item.getString(1));
            stockDaily.setOpened(item.getBigDecimal(2));
            stockDaily.setHigh(item.getBigDecimal(3));
            stockDaily.setLow(item.getBigDecimal(4));
            stockDaily.setClosed(item.getBigDecimal(5));
            stockDaily.setPreClosed(item.getBigDecimal(6));
            stockDaily.setChanged(item.getBigDecimal(7));
            stockDaily.setPctChg(item.getBigDecimal(8));
            stockDaily.setVol(item.getBigDecimal(9));
            stockDaily.setAmount(item.getBigDecimal(10));
            if (StringUtils.isNotEmpty(bears)){
                for(StockBear s :bears){
                    if (s.getTsCode().equals(stockDaily.getTsCode())){
                        stockBear = s;
                        break;
                    }
                }
            }

            if (stockBear ==null){
                stockBear = new StockBear();
                stockBear.setTsCode(item.getString(0));
                stockBear.setClosedPrices(item.getBigDecimal(5).toString());
                flag = item.getBigDecimal(7).compareTo(BigDecimal.ZERO);
                if (flag==0){
                    stockBear.setClosedFlags("0");
                }else if (flag == -1){
                    stockBear.setClosedFlags("1");
                }else {
                    stockBear.setClosedFlags("2");
                }
                for (StockBasic sb :list){
                    if (sb.getTsCode().equals(stockDaily.getTsCode())){

                        bd = stockDaily.getVol().divide(sb.getFloatShare(),2,BigDecimal.ROUND_HALF_UP);
                        stockDaily.setTurnoverRate(bd);
                        stockBear.setTurnoverRates(bd.toString());
                        stockBear.setName(sb.getName());
                        break;
                    }
                }
                stockBearService.insertStockBear(stockBear);
            }else {

                stockBear.setClosedPrices(stockBear.getClosedPrices()+","+item.getBigDecimal(5).toString());
                flag = item.getBigDecimal(7).compareTo(BigDecimal.ZERO);
                if (flag==0){
                    stockBear.setClosedFlags(stockBear.getClosedFlags()+",0");
                }else if (flag == -1){
                    stockBear.setClosedFlags(stockBear.getClosedFlags()+",1");
                }else {
                    stockBear.setClosedFlags(stockBear.getClosedFlags()+",2");
                }
                for (StockBasic sb :list){
                    if (sb.getTsCode().equals(stockDaily.getTsCode())){

                        bd = stockDaily.getVol().divide(sb.getFloatShare(),2,BigDecimal.ROUND_HALF_UP);
                        stockDaily.setTurnoverRate(bd);
                        stockBear.setTurnoverRates(stockBear.getTurnoverRates()+","+bd.toString());
                        break;
                    }
                }
                stockBearService.updateStockBear(stockBear);
            }
            if (stockDaily.getTurnoverRate()!=null){
                stockDailyService.insertStockDaily(stockDaily);
            }


            stockBear = null;
        }
    }

    public void bear(){

        JSONObject request = new JSONObject();
        request.put("api_name","daily");
        request.put("token","fab9535839c57860d2525efff8785ec3942ea386d0d304d7fd762d1b");
        Map<String,Object> params = new HashMap<>();
        params.put("trade_date",DateUtils.dateTime());
        request.put("params",params);
        request.put("fields","ts_code,trade_date,open,high,low,close,pre_close,change,pct_chg,vol,amount");

        String response = HttpUtils.sendPost(stockUrl,request.toJSONString());
        JSONObject jsonObject = JSON.parseObject(response);
        JSONObject data = jsonObject.getJSONObject("data");
        JSONArray items = data.getJSONArray("items");

        StockDaily stockDaily = null;
        StockBear stockBear = null;
        JSONArray item = null;
        BigDecimal bd = null;
        int flag = 0;
        List<StockBear> bears = stockBearService.selectStockBearList(null);
        List<StockBasic> list  = stockBasicService.selectStockBasicList(null);
        for (int i=0;i<items.size();i++){
            item = items.getJSONArray(i);
            stockDaily = new StockDaily();

            stockDaily.setTsCode(item.getString(0));
            stockDaily.setTradeDate(item.getString(1));
            stockDaily.setOpened(item.getBigDecimal(2));
            stockDaily.setHigh(item.getBigDecimal(3));
            stockDaily.setLow(item.getBigDecimal(4));
            stockDaily.setClosed(item.getBigDecimal(5));
            stockDaily.setPreClosed(item.getBigDecimal(6));
            stockDaily.setChanged(item.getBigDecimal(7));
            stockDaily.setPctChg(item.getBigDecimal(8));
            stockDaily.setVol(item.getBigDecimal(9));
            stockDaily.setAmount(item.getBigDecimal(10));

            for(StockBear s :bears){
                if (s.getTsCode().equals(stockDaily.getTsCode())){
                    stockBear = s;
                    break;
                }
            }
            if (stockBear ==null){
                stockBear = new StockBear();
                stockBear.setTsCode(item.getString(0));
                stockBear.setClosedPrices(item.getBigDecimal(5).toString());
                flag = item.getBigDecimal(7).compareTo(BigDecimal.ZERO);
                if (flag==0){
                    stockBear.setClosedFlags("0");
                }else if (flag == -1){
                    stockBear.setClosedFlags("1");
                }else {
                    stockBear.setClosedFlags("2");
                }
                for (StockBasic sb :list){
                    if (sb.getTsCode().equals(stockDaily.getTsCode())){

                        bd = stockDaily.getVol().divide(sb.getFloatShare(),2,BigDecimal.ROUND_HALF_UP);
                        stockDaily.setTurnoverRate(bd);
                        stockBear.setTurnoverRates(bd.toString());
                        stockBear.setName(sb.getName());
                        break;
                    }
                }
                stockBearService.insertStockBear(stockBear);
            }else {

                stockBear.setClosedPrices(stockBear.getClosedPrices()+","+item.getBigDecimal(5).toString());
                flag = item.getBigDecimal(7).compareTo(BigDecimal.ZERO);
                if (flag==0){
                    stockBear.setClosedFlags(stockBear.getClosedFlags()+",0");
                }else if (flag == -1){
                    stockBear.setClosedFlags(stockBear.getClosedFlags()+",1");
                }else {
                    stockBear.setClosedFlags(stockBear.getClosedFlags()+",2");
                }
                for (StockBasic sb :list){
                    if (sb.getTsCode().equals(stockDaily.getTsCode())){

                        bd = stockDaily.getVol().divide(sb.getFloatShare(),2,BigDecimal.ROUND_HALF_UP);
                        stockDaily.setTurnoverRate(bd);
                        stockBear.setTurnoverRates(stockBear.getTurnoverRates()+","+bd.toString());
                        break;
                    }
                }
                stockBearService.updateStockBear(stockBear);
            }
            if (stockDaily.getTurnoverRate()!=null){
                stockDailyService.insertStockDaily(stockDaily);
            }


            stockBear = null;
        }
    }

}
